package com.mskj.zxmy.service.serviceImpl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.date.DateUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.mskj.zxmy.config.PageResult;
import com.mskj.zxmy.dto.*;
import com.mskj.zxmy.entity.*;
import com.mskj.zxmy.mapper.*;
import com.mskj.zxmy.service.StockInService;
import com.mskj.zxmy.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;


import javax.management.Query;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.text.SimpleDateFormat;

@Service
@Slf4j
public class StockInServiceImpl implements StockInService {

    @Autowired
    private StockInMapper stockInMapper;

    @Autowired
    private UserMapper userMapper;
    @Autowired
    private MaterialInfoMapper materialInfoMapper;
    @Autowired
    private GYMapper gyMapper;
    @Autowired
    private SCMapper scMapper;
    @Autowired
    private Gy02ProductRepositoryMapper gy02ProductRepositoryMapper;
    
    @Autowired
    private MyTaskMapper myTaskMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map<String, StockIn> createStockIn() {
        String datePart = DateUtil.format(DateUtil.date(), "yyyyMMdd");

//        // 生成单据号（RK开头）
//        String billNo = generateBillNo(datePart);

        // 生成批次号（PC开头）
        String batchNo = generateBatchNo(datePart);

        StockIn stockIn = StockIn
                .builder()
//                .repositoryNumber(newRepositoryNumber)
                .repositoryDate(DateUtil.date())
                .updateTime(String.valueOf(DateUtil.parse(datePart, "yyyyMMdd")))
                .documentType("生产入库")
                .singleBatch(batchNo) // 使用独立生成的批次号
                .operator(stockInMapper.getUserName((String) StpUtil.getLoginId()))
                .approvalStatus("DRAFT")
                .build();

        // 自动生成repositoryNumber
        String datePartForRepository = new SimpleDateFormat("yyyyMMdd").format(new Date());
        String maxRepositoryNumber = stockInMapper.selectMaxRepositoryNumberByDate(datePartForRepository);
        String newRepositoryNumber;
        if (maxRepositoryNumber == null) {
            newRepositoryNumber = "RK" + datePartForRepository + "0001";
        } else {
            String seqStr = maxRepositoryNumber.substring(maxRepositoryNumber.length() - 4);
            int seq = Integer.parseInt(seqStr) + 1;
            newRepositoryNumber = "RK" + datePartForRepository + String.format("%04d", seq);
        }
        stockIn.setRepositoryNumber(newRepositoryNumber);

        Map<String, StockIn> result = new HashMap<>();
        result.put("stockIn", stockIn);
        return result;
    }

//    @Override
//    public StockIn getByBillNo(String billNo) {
//        return stockInMapper.selectByBillNo(billNo);
//    }

    /**
     * 生成单据编号（RK+YYYYMMDD+两位数字）
     */
//    private String generateBillNo(String datePart) {
//        String maxBillNo = stockInMapper.selectMaxBillNo(datePart);
//        int seq = 1;
//        if (maxBillNo != null) {
//            String seqPart = maxBillNo.substring(10); // 提取RK后面的两位数字
//            seq = Integer.parseInt(seqPart) + 1;
//        }
//        return "RK" + datePart + String.format("%02d", seq);
//    }

    /**
     * 生成批次号（PC+YYYYMMDD+两位数字）
     */
    private String generateBatchNo(String datePart) {
        String maxBatchNo = stockInMapper.selectMaxBatchNo(datePart);
        int seq = 1;
        if (maxBatchNo != null) {
            String seqPart = maxBatchNo.substring(10); // 提取PC后面的两位数字
            seq = Integer.parseInt(seqPart) + 1;
        }
        return "PC" + datePart + String.format("%02d", seq);
    }

//    @Override
//    public boolean confirmStockIn(String id) {
//        int updated = stockInMapper.updateStatusById(id, "CONFIRMED");
//        return updated > 0;
//    }

    @Override
    @Transactional
    public boolean saveStockInWithDetails(StockInSaveDTO dto) {
        // 1. 计算所有明细的入库数量总和
        int totalNumberOfEntries = 0;
        List<StockInDetailSaveDTO> details = dto.getDetails();
        if (details != null && !details.isEmpty()) {
            for (StockInDetailSaveDTO detail : details) {
                if (detail.getNumberOfEntries() != null) {
                    totalNumberOfEntries += detail.getNumberOfEntries();
                }
            }
        }

        // 2. 保存主表
        StockIn stockIn = new StockIn();
        stockIn.setDocumentType(dto.getDocumentType());
        stockIn.setRepositoryNumber(dto.getRepositoryNumber());
        if (StpUtil.getLoginId() != null) {
            stockIn.setOperator(StpUtil.getLoginId().toString());
        }
        stockIn.setRepositoryDate(new Date());
        stockIn.setApprovalStatus("已通过");
        stockIn.setAssociatedSuppliers(stockInMapper.getAssociatedSuppliersId(dto.getAssociatedSuppliers()));
        stockIn.setSingleBatch(dto.getSingleBatch());
        stockIn.setNumberOfReconciliations(totalNumberOfEntries); // 赋值总入库数量

        int mainRes = stockInMapper.insertStockIn(stockIn);
        if (mainRes <= 0) return false;

        // 3. 批量保存明细，使用主表自增id
        if (details != null && !details.isEmpty()) {
            for (StockInDetailSaveDTO detail : details) {
                detail.setScantobaseStatus("未扫码");
                detail.setBatchStatus("未出库");
                detail.setBatchNumber(detail.getBatchNumber());
                if (StpUtil.getLoginId() != null) {
                    detail.setCreator(StpUtil.getLoginId().toString());
                }
                detail.setCreateDate(LocalDate.now());
                detail.setLinkToList(stockIn.getId() == null ? "" : stockIn.getId().toString());
                stockInMapper.insertStockInDetail(detail);
            }
        }
        return true;
    }

    /**
     * 入库状态查询入库单列表
     *
     * @return
     */
//    @Override
//    public List<Ck03Listing> selectAllStockIn(String repositoryStatus) {
//        List<Ck03Listing> ck03Listings = stockInMapper.selectAllStockIn(repositoryStatus);
//        for (Ck03Listing ck03Listing : ck03Listings) {
//            ck03Listing.setOperator(stockInMapper.getAssociatedSuppliersName(ck03Listing.getId()));
//            ck03Listing.setProductionTasks01(stockInMapper.getProductionTasksById(ck03Listing.getProductionTasks()));
//            ck03Listing.setTasks(stockInMapper.getTasksById(ck03Listing.getTasks()));
//        }
//        return ck03Listings;
//    }
    @Override
    public PageInfo<Ck03Listing> selectAllStockInWithPage(StockInListQueryDTO query) {
        PageHelper.startPage(query.getPageNum(), query.getPageSize());
        List<Ck03Listing> ck03Listings = stockInMapper.selectAllStockIn(query.getRepositoryStatus());
        for (Ck03Listing ck03Listing : ck03Listings) {
            ck03Listing.setOperator(stockInMapper.getAssociatedSuppliersName(ck03Listing.getId()));
            ck03Listing.setProductionTasks01(stockInMapper.getProductionTasksById(ck03Listing.getProductionTasks()));
            ck03Listing.setTasks(stockInMapper.getTasksById(ck03Listing.getTasks()));
        }
        return new PageInfo<>(ck03Listings);
    }

    /**
     * 根据入库单号查询入库列表
     *
     * @param repositoryNumber
     * @return
     */
    @Override
    public StockIn selectStockInByNumber(String repositoryNumber) {
        List<StockIn> stockInList = stockInMapper.selectStockInByNumber(repositoryNumber);
        for (StockIn stockIn : stockInList) {
            stockIn.setTasksInfo(gyMapper.getProcessNameById(stockIn.getTasks()));
            stockIn.setProductionTasksInfo(scMapper.getmissionStreamById(stockIn.getProductionTasks()));
            stockIn.setOperator(stockInMapper.getAssociatedSuppliersName(stockIn.getId()));
            for (ProductDetailDTO detailDTO : stockIn.getDetails()) {
                detailDTO.setProductSpecifications(detailDTO.getMaterialCategory() + " " + detailDTO.getTypeOfProduct());

            }
        }
        return stockInList.isEmpty() ? null : stockInList.get(0);
    }

    /**
     * 根据产品入库明细ID返回出库明细
     *
     * @param detailId
     * @return
     */
    @Override
    public ProductDetailDTO getProductInfoByDetailId(String detailId) {
        ProductDetailDTO productDetailDTO = stockInMapper.getProductInfoByDetailId(detailId);
        productDetailDTO.setProductSpecifications(productDetailDTO.getMaterialCategory() + " " + productDetailDTO.getTypeOfProduct());
        return productDetailDTO;
    }

    public ProductDetailDTO getStockInDetailWithProductInfo(Integer batchBarCodeId) {

        BarcodeManagement barcodeManagemen = stockInMapper.getBarcodeManagementBydetailId(batchBarCodeId);

        // 2. 查物品信息
        ProductDetailDTO product = stockInMapper.selectProductDetailByProductId(String.valueOf(barcodeManagemen.getProductName()));
        SctechMissions sctechMissions = stockInMapper.getcurrentProcessTaskById(barcodeManagemen.getCurrentProcessTask());
        Gy02ProductRepository repository = gy02ProductRepositoryMapper.selectByMissionStream(String.valueOf(barcodeManagemen.getProductionTasks()));
        // 3. 组装返回
        ProductDetailDTO result = new ProductDetailDTO();

        // 拷贝产品字段
        if (product != null) {
            result.setProductSpecifications(product.getMaterialCategory() + " " + product.getTypeOfProduct());
            result.setProductId(product.getId());
            result.setProductNumber(product.getProductNumber());
            result.setProductName(product.getProductName());
            result.setBrand(product.getBrand());
            result.setMaterialCategory(product.getMaterialCategory());
            result.setTypeOfProduct(product.getTypeOfProduct());
            result.setEnvironmentalProtectionLevel(product.getEnvironmentalProtectionLevel());
        }
        result.setProductionTaskInfo(repository.getMissionStream());
        result.setTasksInfo(sctechMissions.getProcessName());

        return result;
    }

//    @Override
//    public boolean saveDetail(StockInDetailSaveDTO detail) {
//
//        detail.setBatchStatus("未出库");
//        detail.setScantobaseStatus("已扫码");
//        detail.setCurrentInventory(detail.getNumberOfEntries());
//        detail.setCreateDate(LocalDate.now());
//        detail.setCreator(StpUtil.getLoginId().toString());
//        detail.setUpdater(StpUtil.getLoginId().toString());
//        detail.setUpdateDate(LocalDate.now());
//        detail.setLinkToList(stockInMapper.getlinkToListByrepositoryNumber(detail.getLinkToListOfId()));
//        // 插入明细，返回是否成功
//        return stockInMapper.saveDetail(detail) > 0;
//    }

    @Override
    @Transactional
    public boolean confirmStockInDetail(StockInSaveDTO dto) {
        // 1. 校验所有明细的扫码状态（查数据库）
        if (dto.getDetails() != null && !dto.getDetails().isEmpty()) {
            for (StockInDetailSaveDTO detail : dto.getDetails()) {
                String status = stockInMapper.getScantobaseStatusByDetailId(detail.getId());
                if (!"已扫码".equals(status)) {
                    throw new RuntimeException("子表的某条数据未扫码，不能确认入库！");
                }
            }
        }
        // 2. 正常处理
        int mainRes = stockInMapper.updateRepositoryStatusByNumber(dto.getRepositoryNumber(), "已入库");
//        更新条码主表

        StockIn stockIn = stockInMapper.selectStockInByRepNumber(dto.getRepositoryNumber());
        BarcodeManagement barcodeManagement = new BarcodeManagement();
        barcodeManagement.setModified(StpUtil.getLoginId().toString());
        barcodeManagement.setModified1(LocalDateTime.now());
        barcodeManagement.setValidity("有效");
        barcodeManagement.setProductionTasks(stockIn.getProductionTasks());
        //查询工艺信息
        SctechMissions sctechMissions = stockInMapper.getcurrentProcessTaskById(stockIn.getTasks());
        barcodeManagement.setCurrentProcessTask(sctechMissions.getId());
        ProductDetailDTO product = stockInMapper.getProductInfoByNumber(sctechMissions.getProductInformation());
        barcodeManagement.setProductName(product.getId());
        barcodeManagement.setNumber(stockIn.getNumberOfReconciliations());
        barcodeManagement.setBatchBarCodes(stockIn.getSingleBatch());
//        String pcNumber = barcodeManagement.getBatchBarCodes();
        stockInMapper.updateBybarcodeManagementTable(barcodeManagement);
        barcodeManagement.setId(stockInMapper.getBarcodeManagementByPcNumber(barcodeManagement.getBatchBarCodes()));

        //更新条码子表
        BarCodeManagementDetails barCodeManagementDetails = new BarCodeManagementDetails();
        barCodeManagementDetails.setBindTheProduct(product.getId());
        barCodeManagementDetails.setBarCodeBehavior("生产入库");
        barCodeManagementDetails.setNumber(BigDecimal.valueOf(barcodeManagement.getNumber()));
        barCodeManagementDetails.setCreated(new Date());
        barCodeManagementDetails.setSynchronisingFolderFailedSS(StpUtil.getLoginId().toString());
        barCodeManagementDetails.setLinkBarCodeManagement(barcodeManagement.getId());
        barCodeManagementDetails.setLinkProcessTasks(barcodeManagement.getCurrentProcessTask());
        barCodeManagementDetails.setResponsiblePersons(stockIn.getOperator());
        stockInMapper.savaBarCodeManagementDetails(barCodeManagementDetails);
        
        // 更新主表的number字段 - 根据子表数据计算
        updateBarcodeMainNumber(barcodeManagement.getId());
        boolean allSuccess = true;
        if (dto.getDetails() != null && !dto.getDetails().isEmpty()) {
            for (StockInDetailSaveDTO detail : dto.getDetails()) {
                int res = stockInMapper.updateStockInDetailQuantity(detail.getId(), detail.getNumberOfEntries());
                if (res <= 0) allSuccess = false;
            }
        }
        return mainRes > 0 && allSuccess;
    }


    @Override
    public PageInfo<RealTimeStockDTO> getRealTimeStockWithPage(RealTimeStockQueryDTO query) {
        PageHelper.startPage(query.getPageNum(), query.getPageSize());
        List<RealTimeStockDTO> result = stockInMapper.getRealTimeStockByCondition(
                query.getProductNumber(),
                query.getProductName(),
                query.getProductSpecifications(),
                query.getTypeOfProduct(),
                query.getEnvironmentalProtectionLevel(),
                query.getBrand(),
                query.getBatchNumber(),
                query.getMaterialCategory()
        );
        for (RealTimeStockDTO realTimeStockDTO : result) {
            realTimeStockDTO.setProductSpecifications(realTimeStockDTO.getMaterialCategory() + " " + realTimeStockDTO.getTypeOfProduct());
        }
        return new PageInfo<>(result);
    }

//    @Override
//    public List<RealTimeStockDTO> getRealTimeStockByCondition(String productNumber, String productModel, String productName) {
//        List<RealTimeStockDTO> realTimeStockDTOList = stockInMapper.getRealTimeStockByCondition(productNumber, productName, null, null, null, null, null, null);
//        for (RealTimeStockDTO realTimeStockDTO : realTimeStockDTOList) {
//            realTimeStockDTO.setProductSpecifications(realTimeStockDTO.getMaterialCategory() + " " + realTimeStockDTO.getTypeOfProduct());
//        }
//        return realTimeStockDTOList;
//
//    }

    @Override
    public boolean updateByDetailId(StockInDetailSaveDTO detail) {
        detail.setScantobaseStatus("已扫码");
        String PCNumber = stockInMapper.getbatchNumberByBarcode(detail.getBatchNumberId());
        detail.setBatchNumber(PCNumber);
        boolean result = stockInMapper.updateStatusByDetailId(detail.getBatchNumber(), detail.getNumberOfEntries(), detail.getScantobaseStatus());
        return result;

    }

    /**
     * 入库明细列表
     *
     * @param repositoryStatus
     * @return
     */
//    @Override
//    public List<StockInDetailSaveDTO> getStockInDetails(String repositoryStatus) {
////        PageHelper.startPage(query.getPageNum(), query.getPageSize());
//        List<StockInDetailSaveDTO> result = stockInMapper.getStockInDetails(repositoryStatus);
//        loadProcessingDetailedAssociatedIds(result);
//        return result;
//    }

    /**
     * 分页查询入库明细列表
     *
     * @param query 查询条件
     * @return 分页结果
     */
    @Override
    public PageInfo<StockInDetailSaveDTO> getStockInDetailsWithPage(StockInDetailListQueryDTO query) {
        log.info("=== 入库明细分页查询调试信息 ===");
        log.info("查询参数: repositoryStatus={}, pageNum={}, pageSize={}", 
                query.getRepositoryStatus(), query.getPageNum(), query.getPageSize());
        
        PageHelper.startPage(query.getPageNum(), query.getPageSize());
        List<StockInDetailSaveDTO> result = stockInMapper.getStockInDetails(query.getRepositoryStatus());
        
        log.info("查询结果数量: {}", result != null ? result.size() : 0);
        
        loadProcessingDetailedAssociatedIds(result);
        return new PageInfo<>(result);
    }

    /**
     * 加载入库明细关联的详细信息
     *
     * @param result 入库明细列表，需要填充关联信息的明细数据
     */
    private void loadProcessingDetailedAssociatedIds(List<StockInDetailSaveDTO> result) {
        for (StockInDetailSaveDTO detail : result) {
            detail.setOperator(userMapper.findNickByMemberId(detail.getOperator()));
            detail.setLinkToList(stockInMapper.getlinkToListByrepositoryNumber(detail.getLinkToList()));
            ProductDetailDTO product = stockInMapper.getProductInfoByNumber(detail.getProductInformation());
            if (product != null) {
                detail.setProductInfo(
                        product.getProductName() + " "
                                + product.getMaterialCategory() + " "
                                + product.getEnvironmentalProtectionLevel() + " "
                                + product.getBrand()
                );
            } else {
                detail.setProductInfo("未知物料");
            }
        }
    }

//    @Override
//    public List<StockInDetailSaveDTO> filterStockIn(StockInQueryDTO query) {
//        if (query.getRepositoryStatus() == null || query.getRepositoryStatus().trim().isEmpty()) {
//            throw new IllegalArgumentException("入库状态（repositoryStatus）不能为空");
//        }
//        // 1. 先查物料信息表，获取所有符合条件的物料编号
//        List<String> productNumbers = materialInfoMapper.selectProductNumbersByFilter(
//                query.getProductName(),
//                query.getProductSpecifications(),
//                query.getMaterialCategory(),
//                query.getBrand()
//        );
//        if (productNumbers.isEmpty()) {
//            return Collections.emptyList();
//        }
//        // 2. 再查入库单表，查这些物料编号的入库单
//        List<StockInDetailSaveDTO> result = stockInMapper.selectStockInByProductNumbers(
//                query.getRepositoryNumber(),
//                productNumbers,
//                query.getRepositoryStatus());
//        loadProcessingDetailedAssociatedIds(result);
//        return result;
//    }

    @Override
    public PageInfo<StockInDetailSaveDTO> filterStockInWithPage(StockInQueryDTO query) {
        log.info("=== 入库明细筛选分页查询调试信息 ===");
        log.info("查询参数: repositoryStatus={}, pageNum={}, pageSize={}, productName={}, productSpecifications={}, materialCategory={}, brand={}", 
                query.getRepositoryStatus(), query.getPageNum(), query.getPageSize(), 
                query.getProductName(), query.getProductSpecifications(), query.getMaterialCategory(), query.getBrand());
        
        if (query.getRepositoryStatus() == null || query.getRepositoryStatus().trim().isEmpty()) {
            throw new IllegalArgumentException("入库状态（repositoryStatus）不能为空");
        }
        // 1. 先查物料信息表，获取所有符合条件的物料编号
        List<String> productNumbers = materialInfoMapper.selectProductNumbersByFilterStock(
                query.getProductName(),
                query.getProductSpecifications(),
                query.getMaterialCategory(),
                query.getBrand()
        );
        
        log.info("物料编号查询结果数量: {}", productNumbers != null ? productNumbers.size() : 0);
        log.info("物料编号列表: {}", productNumbers);
        
        if (productNumbers.isEmpty()) {
            log.warn("没有找到符合条件的物料编号，返回空结果");
            return new PageInfo<>(Collections.emptyList());
        }
        // 2. 再查入库单表，查这些物料编号的入库单
        PageHelper.startPage(query.getPageNum(), query.getPageSize());
        List<StockInDetailSaveDTO> result = stockInMapper.selectStockInByProductNumbers(
                query.getRepositoryNumber(),
                productNumbers,
                query.getRepositoryStatus());
        
        log.info("入库明细查询结果数量: {}", result != null ? result.size() : 0);
        
        loadProcessingDetailedAssociatedIds(result);
        return new PageInfo<>(result);
    }

    @Override
    public StockInDetailSaveDTO getStockInDetailById(Integer detailId) {
        StockInDetailSaveDTO detail = stockInMapper.selectStockInDetailById(detailId);
        // 可选：补充物料信息

        if (detail != null) {
            detail.setOperator(userMapper.findNickByMemberId(detail.getOperator()));
            detail.setLinkToList(stockInMapper.getlinkToListByrepositoryNumber(detail.getLinkToList()));
            ProductDetailDTO product = stockInMapper.getProductInfoByNumber(detail.getProductInformation());
            if (product != null) {
                detail.setProductInfo(
                        product.getProductName() + " "
                                + product.getMaterialCategory() + " "
                                + product.getEnvironmentalProtectionLevel() + " "
                                + product.getBrand()
                );
            } else {
                detail.setProductInfo("未知物料");
            }
        }
        return detail;
    }

    /**
     * 根据子表数据更新主表的number字段
     * 逻辑：主表的数量根据最新的条码行为来赋值
     * 1. 获取最新的条码行为和产品名称
     * 2. 对相同条码行为和相同产品名称的数据求和
     * 3. 新的条码行为会覆盖主表之前的数量
     */
    private void updateBarcodeMainNumber(Integer barcodeId) {
        log.info("开始更新条码主表number字段: barcodeId={}", barcodeId);
        
        // 直接使用SQL更新，SQL中已经实现了分组求和和取最大值的逻辑
        int updateResult = myTaskMapper.updateBarcodeMainNumber(barcodeId);
        
        if (updateResult > 0) {
            log.info("条码主表number字段更新成功: barcodeId={}, updateResult={}", barcodeId, updateResult);
        } else {
            log.warn("条码主表number字段更新失败: barcodeId={}, updateResult={}", barcodeId, updateResult);
        }
    }

}